package com.cutefool.zero.code.admin.meta.model.web;

import com.cutefool.core.account.Account;
import com.cutefool.core.account.LoginAccountService;
import com.cutefool.core.res.PageResponse;
import com.cutefool.core.res.Response;
import com.cutefool.dsl.mybatis.core.dsl.builder.DeleteDsl;
import com.cutefool.dsl.mybatis.core.dsl.builder.InsertDsl;
import com.cutefool.dsl.mybatis.core.dsl.builder.QueryDsl;
import com.cutefool.dsl.mybatis.core.dsl.condition.Conditioning;
import com.cutefool.dsl.mybatis.core.dsl.operation.CuteCurdOperation;
import com.cutefool.dsl.mybatis.core.page.Paging;
import com.cutefool.rds.meta.libs.RdsTable;
import com.cutefool.rds.template.RdsTemplate;
import com.cutefool.zero.code.admin.consts.Constants;
import com.cutefool.zero.code.admin.meta.model.dto.ModelDTO;
import com.cutefool.zero.code.admin.meta.model.dto.ModelScriptDTO;
import com.cutefool.zero.code.admin.meta.model.query.ModelQuery;
import com.cutefool.zero.code.admin.meta.model.service.ModelService;
import com.cutefool.zero.code.admin.meta.model.support.ModelDbSupport;
import com.cutefool.zero.code.core.domain.Model;
import com.cutefool.zero.code.core.objects.ValidateDTO;
import jakarta.annotation.Resource;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping(Constants.API_PREFIX)
public class ModelController {

    @Resource
    private ModelService modelService;

    @Resource
    private ModelDbSupport modelDbSupport;

    @Resource
    private LoginAccountService<Account> loginAccountService;

    @Resource
    private CuteCurdOperation<Model> cuteCurdOperation;

    /**
     * 新增
     *
     * @param dto dto
     * @return Response<Long>
     **/
    @PostMapping("/add/models")
    public Response<?> create(@RequestBody @Validated ModelDTO dto) {
        Response<Boolean> validate = this.modelService.validate(null, dto);
        if (validate.isFailure()) {
            return validate;
        }
        InsertDsl<Model> entity = InsertDsl.newInstance(Model.instance()).entity(dto);
        this.cuteCurdOperation.create(entity);
        // 同步到数据库
        RdsTable libs = this.modelDbSupport.doTableLibs(entity.getEntity());
        return Response.ok(new ModelScriptDTO(entity.getEntity().getId(), RdsTemplate.doCreate(libs)));
    }

    /**
     * 校验名称
     *
     * @param dto dto
     * @return Response<Long>
     **/
    @PostMapping("/validate/model-names")
    public Response<?> validateNames(@RequestBody @Validated ValidateDTO dto) {
        boolean b = this.modelService.validateName(dto.getId(), dto.getName());
        return Response.ok(b);
    }

    /**
     * 校验表名
     *
     * @param dto dto
     * @return Response<Long>
     **/
    @PostMapping("/validate/model-table-names")
    public Response<?> validateTableName(@RequestBody @Validated ValidateDTO dto) {
        boolean b = this.modelService.validateName(dto.getId(), dto.getName());
        return Response.ok(b);
    }

    /**
     * 同步到数据库
     *
     * @param id id
     * @return Response<Boolean>
     **/
    @PostMapping("/execute/models/{id}")
    public Response<Boolean> execute(@PathVariable Long id) {
        this.modelDbSupport.doSyncToDb(id);
        return Response.ok();
    }

    /**
     * 删除
     *
     * @param id id
     * @return Response<Boolean>
     **/
    @PostMapping("/delete/models/{id}")
    public Response<Boolean> delete(@PathVariable Long id) {
        DeleteDsl<Model> deleteDsl = DeleteDsl.newInstance(Model.instance(), (where) -> where.and(Model.instance().id(), SqlBuilder.isEqualTo(id)));
        this.cuteCurdOperation.delete(deleteDsl);
        return Response.ok();
    }


    /**
     * 查询（通过ID）
     *
     * @param id id
     * @return Response<Model>
     **/
    @GetMapping("/info/models/{id}")
    public Response<Model> byId(@PathVariable Long id) {
        QueryDsl<Model> queryDsl = QueryDsl.newInstance(Model.instance(), where -> where.and(Model.instance().id(), SqlBuilder.isEqualTo(id)));
        Optional<Model> optional = this.cuteCurdOperation.get(queryDsl);
        return Response.ok(optional.orElse(null));
    }

    /**
     * 查询（列表）
     *
     * @param query query
     * @return Response<List < Model>>
     **/
    @GetMapping("/list/models")
    public Response<List<Model>> list(Conditioning query) {
        query.setCreateBy(loginAccountService.getPresent().getId());
        QueryDsl<Model> queryDsl = QueryDsl.newInstance(Model.instance(), query);
        List<Model> entities = this.cuteCurdOperation.list(queryDsl);
        return Response.ok(entities);
    }

    /**
     * 查询（分页）
     *
     * @param query  query
     * @param paging paging
     * @return Response<PageResponse < Model>>
     **/
    @GetMapping("/page/models")
    public Response<PageResponse<Model>> page(ModelQuery query, Paging paging) {
        QueryDsl<Model> queryDsl = QueryDsl.newInstance(Model.instance(), query, paging);
        PageResponse<Model> response = this.cuteCurdOperation.page(queryDsl);
        return Response.ok(response);
    }
}
